#include "newn.hpp"


[[eosio::action]]
void newn::reveal(const uint64_t& id, const capi_checksum256& seed) {
	//require_auth(REVEALER);           //* 
	stbet bet = find_or_error(id);
	print(">> reveal+:", id);
	//assert_seed(seed, bet.seed_hash); //*

	uint8_t random_roll = compute_random_roll(seed, bet.user_seed_hash);
	asset payout = asset(0, EOS_SYMBOL);
	if (random_roll < bet.roll_under) {
		payout = compute_payout(bet.roll_under, bet.amount);
		print(">> payout:", payout, _self, bet.player);
		action(permission_level{_self, "active"_n},
			   "eosio.token"_n,"transfer"_n,
			   make_tuple(_self, bet.player, payout, winner_memo(bet)))
				.send();
	}
	unlock(bet.amount);
	if (bet.referrer != _self) {
		// defer trx, no need to rely heavily
		send_defer_action(permission_level{_self, "active"_n},
						  "eosio.token"_n,
						  "transfer"_n,
						  make_tuple(_self,
									 bet.referrer,
									 compute_referrer_reward(bet),
									 referrer_memo(bet)));
	}
	remove(bet);
	st_result result{.bet_id = bet.id,
			.player = bet.player,
			.referrer = bet.referrer,
			.amount = bet.amount,
			.roll_under = bet.roll_under,
			.random_roll = random_roll,
			.seed = seed,
			.seed_hash = bet.seed_hash,
			.user_seed_hash = bet.user_seed_hash,
			.payout = payout};

	send_defer_action(permission_level{_self, "active"_n},LOG,"result"_n,make_tuple(bet.amount,payout, seed));
}

void newn::transfer(const name& from,
							const name& to,
							const asset& quantity,
							const string& memo) {
	print(">>newn::transfer from:", from, ",to:", to, ",_self:", _self, ", quantity:", quantity, ",memo:", memo);
	if (from == _self || to != _self) {    // terminate cycle invoke
	 	return;
	}
	// if ("Transfer bonus" == memo) {
	// 	return;
	// }

	uint8_t roll_under;
	capi_checksum256 seed_hash;
	capi_checksum160 user_seed_hash;
	uint64_t expiration;
	name referrer;
	capi_signature sig;
	print(">> before parse_memo:");
	parse_memo(memo, &roll_under, &seed_hash, &user_seed_hash, &expiration, &referrer, &sig);

	// //check quantity
	// assert_quantity(quantity);                                       //*

	// //check roll_under
	// assert_roll_under(roll_under, quantity);

	// //check seed hash && expiration
	// assert_hash(seed_hash, expiration);

	// //check referrer
	// eosio_assert(referrer != from, "referrer can not be self");

	// //check capi_signature
	// assert_signature(roll_under, seed_hash, expiration, referrer, sig); //*
	//
	const stbet bet{.id = next_id(),
			.player = from,
			.referrer = referrer,
			.amount = quantity,
			.roll_under = roll_under,
			.seed_hash = seed_hash,
			.user_seed_hash = user_seed_hash,
			.created_at = now()};
	_strmemo = memo;
	print(">> before save bet:", _strmemo, "<< strmemo>>");
	save(bet);
	lock(quantity);
	print(">> after betting", from, _self, quantity, "betting");

//	action(permission_level{_self, "active"_n},
//			_self,"receipt"_n,
//			_bet)
//			.send();
}

[[eosio::action]]
void newn::receipt(const stbet& bet) {
	//require_auth(_self);
	print(">> receipt", _self);
}
